﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Text.Editor;
using FunctionPoint.Common;
using FunctionPoint.UI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.Diagnostics;
using EnvDTE;
using EnvDTE80;

using System.Management;
using FunctionPoint.Utility;
using Microsoft.VisualStudio.TeamFoundation;
using System.Windows.Input;
using Microsoft.VisualStudio.Text;
using System.Windows;
using FunctionPoint.Services;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.VersionControl.Common;
using FunctionPoint.Adornments;
using Microsoft.VisualStudio.Text.Formatting;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Utilities;
using FunctionPoint.Adornment;
using System.Windows.Controls;
using Microsoft.TeamFoundation.Common;
using Microsoft.VisualStudio.TeamFoundation.WorkItemTracking;

namespace FunctionPoint.UIManagers
{

    /// <summary>
    /// The adornment manager belongs to a particular WpfTextView.  Its purpose is the management of painting the objects based on either being 
    /// dropped on the editor service from the DropHandler.  It will repspond to requests from the owning service to paint or not paint certain work items
    /// 

    public class WpfTextViewAdornmentManager : DependencyObject
    {




        // private List<FunctionPointLocationAdornment> functionPointLocationAdornments;
        private IWpfTextView wpfTextView;
        private EnvDTE.DTE vsShellDTE;
        private EnvDTE80.DTE2 vsshellDTE2;
        //[Export(typeof(AdornmentLayerDefinition))]
        //[Name(FunctionPoint.Common.Constants.VIEWPORT_ADORNMENTLAYERNAME)]
        //[Order(After = PredefinedAdornmentLayers.Selection)]
        //[TextViewRole(PredefinedTextViewRoles.Document)]
        private IAdornmentLayer _adornmentLayer;
        private IFunctionPointManagerService _managementService = null;
        #region DependencyProperties



        #endregion

        #region Properties

        public IFunctionPointManagerService FunctionPointManagementService
        {
            get
            {
                if (_managementService == null)
                    _managementService = ServiceProvider.GlobalProvider.GetService(typeof(SFunctionPointManagerService)) as IFunctionPointManagerService;

                return _managementService;
            }
        }
        public IAdornmentLayer AdornmentLayer
        {
            get
            {
                if (_adornmentLayer == null)
                    _adornmentLayer = wpfTextView.GetAdornmentLayer(FunctionPoint.Common.Constants.VIEWPORT_ADORNMENTLAYERNAME);

                return _adornmentLayer;
            }
        }

        
        #endregion

        #region Constructors -------------------------------------


        public WpfTextViewAdornmentManager(IWpfTextView textView, IServiceProvider serviceProvider)
        {

            wpfTextView = textView;

            textView.LayoutChanged += new EventHandler<TextViewLayoutChangedEventArgs>((sender, args) =>
            {
                RepaintTextViewAdornments(args.NewSnapshot);

            });

        }

        #endregion


        public void RepaintTextViewAdornments(ITextSnapshot snapShot)
        {
            //TODO: It may be more beneficial to not recreate this every time. Especially if there are several work items selected.
            // howver, it does only apply to the visual elements.  still.
            AdornmentLayer.RemoveAllAdornments();

            var selectedWorkItems = FunctionPointManagementService.GetWorkItemsForDisplay();

            selectedWorkItems.ToList().ForEach(workItem =>
            {

                // need to determine if this even affects the page in question.  

                string currentFilePath = wpfTextView.GetFilePath();
                string serverPath = FunctionPointManagementService.GetServerPath(currentFilePath);

                
                if (workItem.ItemPath == serverPath)
                {
                    WorkItemAdornmentHost workItemAdornment = new WorkItemAdornmentHost(workItem, wpfTextView, snapShot);

                    // need to detrmine if it's in the visual span.

                    ITextViewLine adornmentTextViewLine = wpfTextView.GetTextViewLineContainingBufferPosition(
                        workItemAdornment.TrackingPoint.GetPoint(snapShot));

                    if (adornmentTextViewLine != null && (adornmentTextViewLine.VisibilityState == VisibilityState.PartiallyVisible || adornmentTextViewLine.VisibilityState == VisibilityState.FullyVisible))
                    {

                        Canvas.SetLeft(workItemAdornment.VisualElement, adornmentTextViewLine.Left);
                        Canvas.SetTop(workItemAdornment.VisualElement, adornmentTextViewLine.Top);

                        AdornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,
                            null, null, workItemAdornment.VisualElement,
                            new AdornmentRemovedCallback((sender, uiElement) =>
                            {
                               // Debug.WriteLine(string.Format("Adornment Removal Called:{0}, From: {1}", workItemAdornment.WorkItem.Title, sender));
                            }));
                    }
                }
            });


        }

     
    }
}
